import <iostream>;
import <vector>;
import <thread>;
import <chrono>;
import <atomic>;
import <mutex>;
import <string>;
import T_DICT;

using namespace std;
using namespace chrono;
using namespace DICT;

const int NUM_HU_USERS = 16;     // hu用户数量
const int OPS_PER_USER = 100000;  // 每个用户的操作次数
atomic<long long> total_ops(0);  // 总操作完成数
atomic<int> errors(0);
mutex cout_mutex;

// 竞争的深度路径
vector<string> deep_contended_path;

void contended_user_thread(Dict& db, int user_id) {
    string user_name = "hu_contended_" + to_string(user_id);
    int write_count = 0;
    int read_count = 0;

    try {
        for (int i = 0; i < OPS_PER_USER; i++) {
            // 混合读写操作，比如 70% 读，30% 写
            if (i % 10 < 7) {
                // 读操作
                int value = any_cast<int>(db.get_value("su", user_name, deep_contended_path));
                read_count++;
                if (value < 0) {
                    lock_guard<mutex> lock(cout_mutex);
                    cerr << "Error! User " << user_name << " got negative value: " << value << endl;
                    errors++;
                }
            }
            else {
                // 写操作
                int new_value = rand() % 1000;
                db.set("su", user_name, Dict::set_type::value, new_value, deep_contended_path, false);
                write_count++;
            }
            total_ops++;

            if (total_ops % 10000 == 0) {
                lock_guard<mutex> lock(cout_mutex);
                cout << "Total Ops: " << total_ops
                    << " | Errors: " << errors.load()
                    << endl;
            }
        }

        lock_guard<mutex> lock(cout_mutex);
        cout << user_name << " finished. R: " << read_count << " W: " << write_count << endl;

    }
    catch (const exception& e) {
        lock_guard<mutex> lock(cout_mutex);
        cerr << "Exception in " << user_name << ": " << e.what() << endl;
        errors++;
    }
}

int main() {
    try {
        // 初始化数据库 - 关闭所有不必要的功能
        Dict db(
            "su", "contention_test_db", "root",
            0, 0, 0, 0,
            false, false, false, false, "",
            false,
            false
        );
        db.unlock_operation("su");

        cout << "Creating deep contended path...";

        // 直接挨个创建路径
        vector<string> current_path;
        for (int i = 0; i < 10; i++) {
            string level_name = "level" + to_string(i);
            current_path.push_back(level_name);
            db.add("su", "su", Dict::add_type::dict, any(), current_path, false);
        }
        // 创建最终的值节点
        current_path.push_back("hot_value");
        db.add("su", "su", Dict::add_type::value, 0, current_path, false);

        deep_contended_path = current_path;
        cout << "Done. Depth: " << deep_contended_path.size() << endl;

        // 创建测试用户并赋予权限
        cout << "Creating users and setting permissions...";
        for (int i = 0; i < NUM_HU_USERS; i++) {
            string user_name = "hu_contended_" + to_string(i + 1);
            db.add_user("su", "su", user_name, Dict::UserType::hu, Dict::Permission::rw);

            db.set_permission(
                "su", "su", user_name,
                Dict::SetType::node,
                Dict::Permission::rw,
                true, false, {},
                deep_contended_path
            );
        }
        cout << "Done." << endl;

        cout << "\nStarting extreme contention test..." << endl;
        cout << "Threads: " << NUM_HU_USERS << ", Ops per thread: " << OPS_PER_USER << endl;
        cout << "Target path: /";
        for (const auto& s : deep_contended_path) cout << s << "/";
        cout << endl;

        vector<thread> threads;
        auto start_time = high_resolution_clock::now();

        for (int i = 0; i < NUM_HU_USERS; i++) {
            threads.emplace_back(contended_user_thread, ref(db), i + 1);
        }

        for (auto& t : threads) {
            t.join();
        }

        auto end_time = high_resolution_clock::now();
        auto duration = duration_cast<milliseconds>(end_time - start_time);
        auto total_op_count = total_ops.load();

        cout << "\n=== Extreme Contention Test Results ===" << endl;
        cout << "Total operations (R+W): " << total_op_count << endl;
        cout << "Errors: " << errors.load() << endl;
        cout << "Total time: " << duration.count() << "ms" << endl;

        if (duration.count() > 0) {
            double ops_per_sec = (total_op_count / (duration.count() / 1000.0));
            cout << "Operations per second: " << ops_per_sec << endl;
        }

        if (errors == 0) {
            cout << "\nRESILIENCE TEST PASSED!" << endl;
        }
        else {
            cout << "\nTEST FAILED!" << endl;
        }

        // 验证最终值
        try {
            int final_value = any_cast<int>(db.get_value("su", "su", deep_contended_path));
            cout << "Final value: " << final_value << endl;
        }
        catch (const exception& e) {
            cerr << "Failed to read final value: " << e.what() << endl;
        }

    }
    catch (const exception& e) {
        cerr << "Main exception: " << e.what() << endl;
        return 1;
    }

    return 0;
}